 package de.fme.tracking;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.alfresco.util.Pair;

/**
 * POJO - Parameters controlling feedback queries.
 * 
 * @author jploetz
 * @since 4.0
 */
public class FeedbackQueryParameters
{
    private String pubEventUuid;
    private String pubChannelUuid;
    private Long feedbackEnryId;
    private Long typeEntryId;		//type name or typeEntry Id?
    private Long userEntryId;		//user name or userEntry Id?
    private Long fromEntryId;
    private Long toEntryId;
    private Date fromDate;
    private Date toDate;
    private List<Pair<String, Serializable>> searchKeyValues;
    
    /**
	 * @return the pubEventUuid
	 */
	public String getPubEventUuid() {
		return pubEventUuid;
	}

	/**
	 * @param pubEventUuid the pubEventUuid to set
	 */
	public void setPubEventUuid(String pubEventUuid) {
		this.pubEventUuid = pubEventUuid;
	}

	/**
	 * @return the pubChannelUuid
	 */
	public String getPubChannelUuid() {
		return pubChannelUuid;
	}

	/**
	 * @param pubChannelUuid the pubChannelUuid to set
	 */
	public void setPubChannelUuid(String pubChannelUuid) {
		this.pubChannelUuid = pubChannelUuid;
	}

	/**
	 * @return the feedbackEnryId
	 */
	public Long getFeedbackEnryId() {
		return feedbackEnryId;
	}

	/**
	 * @param feedbackEnryId the feedbackEnryId to set
	 */
	public void setFeedbackEnryId(Long feedbackEnryId) {
		this.feedbackEnryId = feedbackEnryId;
	}

	/**
	 * @return the typeEntryId
	 */
	public Long getTypeEntryId() {
		return typeEntryId;
	}

	/**
	 * @param typeEntryId the typeEntryId to set
	 */
	public void setTypeEntryId(Long typeEntryId) {
		this.typeEntryId = typeEntryId;
	}

	/**
	 * @return the userEntryId
	 */
	public Long getUserEntryId() {
		return userEntryId;
	}

	/**
	 * @param userEntryId the userEntryId to set
	 */
	public void setUserEntryId(Long userEntryId) {
		this.userEntryId = userEntryId;
	}

	/**
	 * @return the fromEntryId
	 */
	public Long getFromEntryId() {
		return fromEntryId;
	}

	/**
	 * @param fromEntryId the fromEntryId to set
	 */
	public void setFromEntryId(Long fromEntryId) {
		this.fromEntryId = fromEntryId;
	}

	/**
	 * @return the toEntryId
	 */
	public Long getToEntryId() {
		return toEntryId;
	}

	/**
	 * @param toEntryId the toEntryId to set
	 */
	public void setToEntryId(Long toEntryId) {
		this.toEntryId = toEntryId;
	}

	/**
	 * @return the fromDate
	 */
	public Date getFromDate() {
		return fromDate;
	}

	/**
	 * @param fromDate the fromDate to set
	 */
	public void setFromDate(Date fromDate) {
		this.fromDate = fromDate;
	}

	/**
	 * @return the toDate
	 */
	public Date getToDate() {
		return toDate;
	}

	/**
	 * @param toDate the toDate to set
	 */
	public void setToDate(Date toDate) {
		this.toDate = toDate;
	}

	
    /**
     * Defaults:<br/>
     * &nbsp;<code>forward = true;</code><br/>
     * &nbsp;<code>searchKeyValues = emptylist</code><br/>
     * &nbsp:<code>others = null</code>
     */
    public FeedbackQueryParameters()
    {
        searchKeyValues = new ArrayList<Pair<String,Serializable>>();
    }
    
    /**
     * @return                  Returns <tt>true</tt> if any query using these parameters will
     *                          necessarily yield no results.
     */
    public boolean isZeroResultQuery()
    {
        if (fromEntryId != null && toEntryId != null && fromEntryId.compareTo(toEntryId) > 0)
        {
            // Inverted IDs
            return true;
        }
        if (fromDate != null && toDate != null && fromDate.compareTo(toDate) > 0)
        {
            // Inverted IDs
            return true;
        }
        return false;
    }

    /**
     * 
     * @return                  Returns the search keys for the query
     */
    public List<Pair<String, Serializable>> getSearchKeyValues()
    {
        return Collections.unmodifiableList(searchKeyValues);
    }

    /**
     * Add a search key pair.
     * 
     * @param searchKey         the path-value pair.  Either the path ({@link Pair#getFirst() first} value)
     *                          or the search value ({@link Pair#getSecond() second} value) may be <tt>null</tt>,
     *                          but not both.
     */
    public void addSearchKey(String searchKey, Serializable searchValue)
    {
        if (searchKey == null && searchValue == null)
        {
            throw new IllegalArgumentException("A search key must have a 'searchKey' and/or a 'searchValue'.");
        }
        if (searchKeyValues.size() > 0)
        {
            throw new UnsupportedOperationException("Only one search key-value pair is currently supported.");
        }
            
        this.searchKeyValues.add(new Pair<String, Serializable>(searchKey, searchValue));
	}
}
